<?php
	/**
	  * @name		Dir
	  * @author		Hermann D. Schimpf <hschimpf@gschimpf.com>
	  * @license	http://opensource.org/licenses/gpl-2.0.php
	  * @date		2010-08-06
	  * @version	0.1.0
  	**/

	class Dir {
		/**
		 * Directorio de la instancia
		 * @var String $path
		 */
		private $path = null;
		private $mtime = null;
		/**
		 * Instancia local de Directory
		 * @var Directory $dirInstance
		 */
		private $dirInstance = null;
		/**
		 * Entradas del directorio
		 * @var Array $entries
		 */
		private $entries = Array();
		/**
		 * Constructor de la clase
		 * @param String Directorio a explorar
		 * @throw DirException
		 */
		public function __construct($dir, $walk = True) {
			/* verificamos si el parametro es un directorio */
			if (!is_dir($dir))
				/* salimos con una excepcion */
				throw new DirException;
			/* almacenamos el directorio */
			$this->setPath($dir);
			/* verificamos si recorremos */
			if ($walk)
				/* recorremos la carpeta actual */
				$this->walk();
		}
		/**
		 * Retorna las entradas del directorio
		 * @return {Dir|File}[] Entradas del directorio
		 */
		public function getEntries() {
			/* verificamos si se recorrio */
			if ($this->dirInstance === null)
				/* recorremos la carpeta */
				$this->walk();
			/* retornamos las entradas */
			return $this->entries;
		}
		/**
		 * Retorna el nombre de la instancia (Ruta)
		 * @return String Nombre de la instancia
		 */
		public function getName() {
			/* retornamos el path */
			return $this->path;
		}
		/**
		 * Retorna la fecha de modificacion del directorio
		 * @return String Fecha de Modificacion
		 */
		public function getMTime() {
			/* retornamos la fecha de modificacion */
			return $this->mtime;
		}
		/**
		 * Muestra la clase en pantalla
		 * @return String
		 */
		public function __toString() {
			/* retornamos la clase en un String */
			return "\n[" . __CLASS__ . '] ' . $this->getPath() . " {{$this->getEntriesToString()}}";
		}
		/**
		 * Arma la lista de entradas como string
		 * @return String Lista de entradas
		 */
		private function getEntriesToString() {
			/* verificamos si no hay entradas en el directorio */
			if (count($this->entries) == 0)
				/* retornamos vacio */
				return null;
			/* creamos una variable temporal para la cadena */
			$result = "\n";
			/* recorremos las entradas */
			foreach ($this->entries AS $entry => $entryData)
				/* agregamos la entrada al resultado */
				$result .= "\t$entry\n";
			/* retornamos el resultado */
			return $result;
		}
		/**
		 * Recorre el directorio actual
		 */
		private function walk() {
			/* almacenamos la ruta actual */
			$path = getcwd();
			/* nos posicionamos en el directorio */
			chdir($this->getPath());
			/* obtenemos una instancia de Directory */
			$this->dirInstance = dir('./');
			/* leemos cada una de las entradas */
			while (($entry = $this->dirInstance->read()) !== False) {
				/* verificamos que no sea . ni .. */
				if ($entry != '.' && $entry != '..')
					/* agregamos la entrada actual */
					$this->addEntry($entry);
			}
			/* nos volvemos a posicionar en el directorio inicial */
			chdir($path);
		}
		/**
		 * Agrega una entrada al arbol
		 * @param String Nombre del Fichero o Directorio
		 */
		private function addEntry($entry) {
			/* agregamos el fichero/directorio al arbol */
			$this->entries[$entry] = (
				/* verificamos si es un directorio */
				is_dir($entry) ?
				/* lo agregamos como instancia de Dir */
				new Dir($entry, False) :
				/* lo agregamos como instancia de File */
				new File($entry)
			);
		}
		/**
		 * Almacena el nombre del directorio
		 * @param String Directorio
		 */
		private function setPath($path) {
			/* almacenamos el directorio */
			$this->path = $path;
			/* almacenamos la fecha de modificacion */
			$this->mtime = date('Y-m-d H:i:s', filemtime($this->getName()));
		}
		/**
		 * Retorna el nombre del directorio
		 * @return String Nombre del directorio
		 */
		private function getPath() {
			/* retornamos la ruta */
			return $this->path;
		}
	}
?>